#include "Acomb_resonance.h"

bool Combine_Charged_Higgs(CDraw &para, AComb_LTV &signal_vis, AComb_LTV &signal_met, ACuts_Vector &cuts_vector){
//	para.debug.Message(3,51,"in Combine_Charged_Higgs :begin");

	//signal_charged_higgs.Print("Charged Higgs before");
	//bool JMbb=signal_charged_higgs.Combine_Met(signal_vis, signal_met);
	//if(!JMbb){return(false);}
	//signal_charged_higgs.Print("Charged Higgs after");

//	para.debug.Message(3,51,"in Combine_Charged_Higgs :end");
	return(true);
}

// /****************************************************************************
///  brief: Find_CH_Combination 
///
///  param: para
///  param: lep
///  param: jet
///  param: met
///  param: cuts
///  param: signal_CH
///  all input TLV (except MET ) are in in.in1, MET is in in.in2
///  TLV used for CH are in out.out1, re-MET is in out.out2
///  CH is in out.comb
///  others are in out.left1
///  
// ****************************************************************************/
void Find_CH_Combination(CDraw &para, AComb_LTV &lep, AComb_LTV &jet, AComb_LTV &met, ACuts &cuts, AComb_LTV &signal_CH){

	std::vector<TLorentzVector> vis_in;
	vis_in =lep.Out_All();
	vis_in += jet.Out_All();
	vis_in.push_back(jet.Left()[0]);

	signal_CH.Add_In(vis_in,1);


	float r1=100000, r2=100000, r3=100000;


	//ShowMessage(2,"in Find_CH_Combination, begin");
	//lep.Print("lep");
	//jet.Print("jet");
	//met.Print("met");
	std::vector<TLorentzVector> vis1;
	TLorentzVector met1;
	TLorentzVector Vmet1, Vcomb1;
	vis1.push_back(lep.Comb());
	vis1.push_back(jet.Left()[0]);
	met1 = met.In()[0];
	signal_CH.Add_In(met1,-1);
	//ShowMessage(2,"in Find_CH_Combination, ", " before reconstruct_met 1", vis1, met1 );
	bool J_recon = reconstruct_met(para, vis1, met1, cuts, Vmet1, Vcomb1);
	//ShowMessage(2,"in Find_CH_Combination,  after reconstruct_met 1", Vmet1, Vcomb1, J_recon );

	if (J_recon){
		r1 = abs(Vcomb1.M()-cuts.m.obj);
	}

	std::vector<TLorentzVector> vis2;
	TLorentzVector met2;
	TLorentzVector Vmet2, Vcomb2;
	//ShowMessage(2,"in Find_CH_Combination, vis2");
	vis2.push_back(lep.Out()[0]);
	vis2.push_back(jet.Comb());
	met2 = met.In()[0];
	//ShowMessage(2,"in Find_CH_Combination, ", " before reconstruct_met 2", vis2, met2 );
	J_recon = reconstruct_met(para, vis2, met2, cuts, Vmet2, Vcomb2);
	//ShowMessage(2,"in Find_CH_Combination,  after reconstruct_met 2", Vmet2, Vcomb2 , J_recon );
	if (J_recon){
		r2 = abs(Vcomb2.M()-cuts.m.obj);
	}

	std::vector<TLorentzVector> vis3;
	TLorentzVector met3;
	TLorentzVector Vmet3, Vcomb3;
	//ShowMessage(2,"in Find_CH_Combination, vis3");
	vis3.push_back(lep.Out()[1]);
	vis3.push_back(jet.Comb());
	met3 = met.In()[0];
	//ShowMessage(2,"in Find_CH_Combination, ", " before reconstruct_met 3", vis3, met3 );
	J_recon = reconstruct_met(para, vis3, met3, cuts, Vmet3, Vcomb3);
	//ShowMessage(2,"in Find_CH_Combination,  after reconstruct_met", Vmet3, Vcomb3 );
	if (J_recon){
		r3 = abs(Vcomb3.M()-cuts.m.obj);
	}


	if(r1==100000&&r2==100000&&r3==100000){
		// if there is no solution for three cases, it means in reconstruct_met,  the range for wmass is too small,
		// but it is waste of time to enlarge the range, and repeat every thing
		// thus, directly set a very large center value.
		cuts.m.obj=1000;
	    reconstruct_met(para, vis3, met3, cuts, Vmet3, Vcomb3);
	}
	
	//ShowMessage(2, "after recon r1 , r2, r3", r1, r2, r3);
	signal_CH.Set_Kind(2);
	if(r1 > r2){
		if(r2 > r3){
			// min is 3
			//ShowMessage(2, "add out",3);
			signal_CH.Add_Out(vis3,1);
			signal_CH.Add_Out(Vmet3,-1);
			signal_CH.Add_Left(lep.Out()[0],1);
			signal_CH.Add_Left(jet.Left()[0],1);
			signal_CH.Set_Comb_with_Pos();
			//ShowMessage(2, "out",signal_CH.Out_All());
			//ShowMessage(2, "comb",signal_CH.Comb());
			//ShowMessage(2, "Vcomb",Vcomb3);
			//signal_CH.Print("finish signal _CH");

		}
		else{
			// min is 2
			//ShowMessage(2, "add out",2);
			signal_CH.Add_Out(vis2,1);
			signal_CH.Add_Out(Vmet2,-1);
			signal_CH.Add_Left(lep.Out()[1],1);
			signal_CH.Add_Left(jet.Left()[0],1);
			signal_CH.Set_Comb_with_Pos();
			//ShowMessage(2, "out",signal_CH.Out_All());
			//ShowMessage(2, "comb",signal_CH.Comb());
			//ShowMessage(2, "Vcomb",Vcomb2);
			//signal_CH.Print("finish signal _CH");
		}
	}
	else{
		if(r1>r3){
			//min is 3
			//ShowMessage(2, "add out",3);
			signal_CH.Add_Out(vis3,1);
			signal_CH.Add_Out(Vmet3,-1);
			signal_CH.Add_Left(lep.Out()[0],1);
			signal_CH.Add_Left(jet.Left()[0],1);
			signal_CH.Set_Comb_with_Pos();
			//ShowMessage(2, "out",signal_CH.Out_All());
			//ShowMessage(2, "comb",signal_CH.Comb());
			//ShowMessage(2, "Vcomb",Vcomb3);
			//signal_CH.Print("finish signal _CH");
		}
		else{
			//min is 1
			//ShowMessage(2, "add out",1);
			signal_CH.Add_Out(vis1,1);
			signal_CH.Add_Out(Vmet1,-1);
			signal_CH.Add_Left(jet.Out()[0],1);
			signal_CH.Add_Left(jet.Out()[1],1);
			signal_CH.Set_Comb_with_Pos();
			//ShowMessage(2, "out",signal_CH.Out_All());
			//ShowMessage(2, "comb",signal_CH.Comb());
			//ShowMessage(2, "Vcomb",Vcomb1);
			//signal_CH.Print("finish signal _CH");
		}
	}
}

bool reconstruct_met(CDraw &para, std::vector<TLorentzVector>& Vvis_input, TLorentzVector &met, ACuts &cuts,  TLorentzVector &Vmet, TLorentzVector &Vcombine){
	if(Vvis_input.size()<1){
		return(false);
	}

	TLorentzVector vis;
	for (int i=0; i<Vvis_input.size(); i++){
		vis += Vvis_input[i];
	}

	bool J_w=AN_RC_w_lnu(para,cuts.m.obj,cuts.m.d,cuts.m.u,vis,met,Vcombine,Vmet);

	return(J_w);

}
